package com.example.myfirstgame.controller;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.example.myfirstgame.helper.DataInstance;

public class GameObjectContainer extends ControllerConstants {

	private Set<GameObject> mGameObjectSet = null;
	private ArrayList<GameObject> mSortedListForDrawing = null;
	private boolean isDrawingListUpToDate = false;
	private CollisionListener mCollisionListener = null;

	public GameObjectContainer() {
		mGameObjectSet = new HashSet<GameObject>();
		mSortedListForDrawing = new ArrayList<GameObject>();
	}

	public GameObjectContainer(CollisionListener pCollisionListener) {
		mGameObjectSet = new HashSet<GameObject>();
		mSortedListForDrawing = new ArrayList<GameObject>();
		mCollisionListener = pCollisionListener;
		mCollisionListener.bindToGameObjectContainer(this);
	}

	public void add(GameObject pGameObject) {
		if (pGameObject != null) {
			mGameObjectSet.add(pGameObject);
			isDrawingListUpToDate = false;
		}
	}

	public void add(GameObject[] pGameObjectArray) {

		if (pGameObjectArray != null) {

			for (GameObject lGameObject : pGameObjectArray) {
				mGameObjectSet.add(lGameObject);

			}

			isDrawingListUpToDate = false;
		}
	}

	public void add(ArrayList<GameObject> pGameObjectList) {

		if (pGameObjectList != null) {

			for (GameObject lGameObject : pGameObjectList) {
				mGameObjectSet.add(lGameObject);

			}

			isDrawingListUpToDate = false;
		}
	}

	public void remove(GameObject pGameObject) {
		mGameObjectSet.remove(pGameObject);
		isDrawingListUpToDate = false;
	}

	public ArrayList<GameObject> deliverSortedListForDrawing() {

		if (!isDrawingListUpToDate && mGameObjectSet != null) {
			refreshSortedListForDrawing();
			if (mSortedListForDrawing.size() >= 1) {
				return mSortedListForDrawing;
			} else {
				return null;
			}
		} else {
			return mSortedListForDrawing;
		}

	}

	public void scaleAllGameObjects(float pFactor, int pRasterSize) {
		DataInstance.getInstance().setGameObjectScalingFactor(pFactor);
		if (mGameObjectSet != null) {
			Iterator<GameObject> lIteratorGameObject = mGameObjectSet
					.iterator();
			while (lIteratorGameObject.hasNext()) {

				GameObject lCurrentGameObject = lIteratorGameObject.next();
				lCurrentGameObject.scaleObject(pFactor, pRasterSize);
			}
		}
	}

	private void refreshSortedListForDrawing() {

		Set<GameObject> lAllGameObjectList = new HashSet<GameObject>(
				mGameObjectSet);
		mSortedListForDrawing.clear();

		ArrayList<String> lAllGameObjectTypes = deliverGameObjectTypeDrawingOrder();

		// Sort the GameObjects

		for (String classType : lAllGameObjectTypes) {

			Iterator<GameObject> lIteratorGameObject = lAllGameObjectList
					.iterator();
			while (lIteratorGameObject.hasNext()) {

				GameObject lCurrentGameObject = lIteratorGameObject.next();
				String lCurrentGameObjectType = lCurrentGameObject
						.getGameType();

				if (lCurrentGameObjectType.equals(classType)) {

					mSortedListForDrawing.add(lCurrentGameObject);
					lIteratorGameObject.remove();

				}
			}
		}

		// All remaining GameObjects will be added without a special order
		for (GameObject lGameObject : lAllGameObjectList) {

			mSortedListForDrawing.add(lGameObject);

		}
		lAllGameObjectList = null;
		isDrawingListUpToDate = true;
	}

	public boolean isDrawingListUpToDate() {
		return isDrawingListUpToDate;
	}

	public void bindCollisionListener(CollisionListener pCollisionListener) {
		mCollisionListener = pCollisionListener;
		mCollisionListener.bindToGameObjectContainer(this);
	}

	public ArrayList<CollisionObject> deliverAllCollitionObjects() {

		if (!isDrawingListUpToDate && mGameObjectSet != null) {
			refreshSortedListForDrawing();
			if (mSortedListForDrawing.size() >= 1) {
				new ArrayList<CollisionObject>(mSortedListForDrawing);
				return new ArrayList<CollisionObject>(mSortedListForDrawing);
			} else {
				return null;
			}
		} else {
			return new ArrayList<CollisionObject>(mSortedListForDrawing);
		}

	};

}
